package com.yuanda.erp9.syn.config;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.alibaba.druid.wall.WallConfig;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.yuanda.erp9.syn.contant.DatabaseGlobal;
import com.yuanda.erp9.syn.core.CustomizedSqlInjector;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.JdbcType;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName MybatisPlusConfig
 * @Description 配置文件-自定义sql注入器
 * @Date 2022/11/16
 * @Author myq
 */
@MapperScan({"com.yuanda.erp9.syn.mapper.erp9", "com.yuanda.erp9.syn.mapper.rate" ,
        "com.yuanda.erp9.syn.mapper.erp9_precrm","com.yuanda.erp9.syn.mapper.erp9_pvestandard",
        "com.yuanda.erp9.syn.mapper.dyj_middledata"})
@Configuration
@EnableTransactionManagement
@ConfigurationProperties(prefix = "mybatis-plus")
public class MybatisPlusConfig {

    private Class logImpl;

    static {
        System.setProperty("druid.mysql.usePingMethod", "false");
    }


    @Bean
    public CustomizedSqlInjector customizedSqlInjector() {
        return new CustomizedSqlInjector();
    }

    @Bean
    public WallConfig wallConfig() {
        WallConfig config = new WallConfig();
        config.setMultiStatementAllow(true);//允许一次执行多条语句
        config.setNoneBaseStatementAllow(true);//允许非基本语句的其他语句
        return config;
    }

    @Bean(name = DatabaseGlobal.erp9)
    @ConfigurationProperties(prefix = "spring.datasource.erp9")
    public DataSource erp9() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = DatabaseGlobal.rate)
    @ConfigurationProperties(prefix = "spring.datasource.rate")
    public DataSource rate() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = DatabaseGlobal.erp9_pveCrm)
    @ConfigurationProperties(prefix = "spring.datasource.erp9-pve-crm")
    public DataSource erp9PveCrm() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = DatabaseGlobal.erp9_pvestandard)
    @ConfigurationProperties(prefix = "spring.datasource.erp9-pvestandard")
    public DataSource erp9PveStandard() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = DatabaseGlobal.dyj_middleData)
    @ConfigurationProperties(prefix = "spring.datasource.dyj-middle-data")
    public DataSource dyjMiddleData() {
        return DruidDataSourceBuilder.create().build();
    }

    /**
     * 动态数据源配置
     *
     * @return
     */
    @Bean
    @Primary
    public DataSource multipleDataSource(
            @Qualifier(DatabaseGlobal.erp9) DataSource erp9DataSource,
            @Qualifier(DatabaseGlobal.rate) DataSource rateDataSource,
            @Qualifier(DatabaseGlobal.erp9_pveCrm) DataSource erp9PveCrmDataSource,
            @Qualifier(DatabaseGlobal.erp9_pvestandard) DataSource erp9PveStandardDataSource,
            @Qualifier(DatabaseGlobal.dyj_middleData) DataSource dyjMiddleDataSource) {
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        Map<Object, Object> targetDataSources = new HashMap<Object, Object>();
        targetDataSources.put(DatabaseGlobal.erp9, erp9DataSource);
        targetDataSources.put(DatabaseGlobal.rate, rateDataSource);
        targetDataSources.put(DatabaseGlobal.erp9_pveCrm, erp9PveCrmDataSource);
        targetDataSources.put(DatabaseGlobal.erp9_pvestandard, erp9PveStandardDataSource);
        targetDataSources.put(DatabaseGlobal.dyj_middleData, dyjMiddleDataSource);
        dynamicDataSource.setTargetDataSources(targetDataSources);
        // 程序默认数据源，这个要根据程序调用数据源频次，经常把常调用的数据源作为默认
        dynamicDataSource.setDefaultTargetDataSource(erp9DataSource);
        return dynamicDataSource;
    }


    @Bean("sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier(DatabaseGlobal.erp9) DataSource erp9DataSource,
                                               @Qualifier(DatabaseGlobal.rate) DataSource rateDataSource,
                                               @Qualifier(DatabaseGlobal.erp9_pveCrm) DataSource erp9PveCrmDataSource,
                                               @Qualifier(DatabaseGlobal.erp9_pvestandard) DataSource erp9PveStandardDataSource,
                                               @Qualifier(DatabaseGlobal.dyj_middleData) DataSource dyjMiddleDataSource) throws Exception {
        MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
        // 多数据源必须设置
        sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:xml/**/*Mapper.xml"));
        sqlSessionFactory.setDataSource(multipleDataSource(erp9DataSource, rateDataSource, erp9PveCrmDataSource,erp9PveStandardDataSource,dyjMiddleDataSource));
        MybatisConfiguration configuration = new MybatisConfiguration();
        configuration.setJdbcTypeForNull(JdbcType.NULL);
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setCacheEnabled(false);
        configuration.setLogImpl(logImpl);
        sqlSessionFactory.setGlobalConfig(globalConfiguration());
        sqlSessionFactory.setConfiguration(configuration);
        return sqlSessionFactory.getObject();
    }

    @Bean
    public GlobalConfig globalConfiguration() {
        GlobalConfig conf = new GlobalConfig();
        // 自定义的注入需要在这里进行配置
        conf.setSqlInjector(customizedSqlInjector());
        return conf;
    }


}